<?php
/**
 * DBShop 电子商务系统
 *
 * ==========================================================================
 * @link      https://www.dbshop.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   https://www.dbshop.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace Goods\Service;

use Doctrine\ORM\EntityManager;
use Goods\Entity\GoodsInSpecGoods;
use Goods\Entity\GoodsInSpecGoodsGroupPrice;
use function Doctrine\ORM\QueryBuilder;

class GoodsInSpecGoodsManager
{
    private $entityManager;

    public function __construct(
        EntityManager $entityManager
    )
    {
        $this->entityManager = $entityManager;
    }

    /**
     * 添加规格商品
     * @param array $data
     * @param $goodsId
     * @return string
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     * @throws \Doctrine\Persistence\Mapping\MappingException
     */
    public function addInSpecGoods(array $data, $goodsId)
    {
        $specGoodsItemStr = '';
        if(isset($data['specTagIdStr']) && !empty($data['specTagIdStr'])) foreach ($data['specTagIdStr'] as $key => $tagIdStr) {
            $idArray    = explode('-', $tagIdStr);
            sort($idArray);
            $idStr      = implode('', $idArray);

            $inSpecGoods = new GoodsInSpecGoods();
            $inSpecGoods->valuesSet([
                'specTagId' => $tagIdStr,
                'tagIdStr'  => $idStr,
                'specGoodsPrice' => $data['specGoodsPrice'][$key],
                'specGoodsStock' => $data['specGoodsStock'][$key],
                'specGoodsItem'  => $data['specGoodsItem'][$key],
                'specGoodsWeight'=> $data['specGoodsWeight'][$key],
                'specGoodsUserGroupPrice' => serialize($data['specGoodsUserGroupPrice'][$tagIdStr]),
                'goodsId' => $goodsId
            ]);
            $this->entityManager->persist($inSpecGoods);
            $this->entityManager->flush();
            $this->entityManager->clear(GoodsInSpecGoods::class);

            $specGoodsItemStr .= $data['specGoodsItem'][$key] . ',';
        }
        return empty($specGoodsItemStr) ? '' : ',' . $specGoodsItemStr;
    }

    /**
     * 编辑规格商品
     * @param array $data
     * @param $goodsId
     * @return string
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     * @throws \Doctrine\Persistence\Mapping\MappingException
     */
    public function editInSpecGoods(array $data, $goodsId)
    {
        $specGoodsItemStr = '';
        if(isset($data['specTagIdStr']) && !empty($data['specTagIdStr'])) {
            $inSpecGoodsIdArray = [];
            $inSpecGoods        = $this->entityManager->getRepository(GoodsInSpecGoods::class)->findBy(['goodsId' => $goodsId]);
            if($inSpecGoods) foreach ($inSpecGoods as $sgValue) {
                if(!in_array($sgValue->getSpecTagId(), $data['specTagIdStr'])) {
                    $this->entityManager->remove($sgValue);
                } else {
                    $key = array_search($sgValue->getSpecTagId(), $data['specTagIdStr']);
                    $sgValue->valuesSet([
                        'specGoodsPrice' => $data['specGoodsPrice'][$key],
                        'specGoodsStock' => $data['specGoodsStock'][$key],
                        'specGoodsItem'  => $data['specGoodsItem'][$key],
                        'specGoodsWeight'=> $data['specGoodsWeight'][$key],
                        'specGoodsUserGroupPrice' => serialize($data['specGoodsUserGroupPrice'][$sgValue->getSpecTagId()])
                    ]);

                    $specGoodsItemStr .= $data['specGoodsItem'][$key] . ',';

                    $inSpecGoodsIdArray[] = $sgValue->getInSpecGoodsId();

                    //这里进行一次tagId排序的重置，必须是从小到大用 - 分隔
                    $idArray    = explode('-', $sgValue->getSpecTagId());
                    sort($idArray);
                    $idStr      = implode('', $idArray);
                    if ($sgValue->getTagIdStr() != $idStr) $sgValue->setTagIdStr($idStr);

                    unset($data['specTagIdStr'][$key]);
                }
                $this->entityManager->flush();
            }

            if(!empty($data['specTagIdStr'])) foreach ($data['specTagIdStr'] as $key => $tagIdStr) {
                $idArray    = explode('-', $tagIdStr);
                sort($idArray);
                $idStr      = implode('', $idArray);

                $inSpecGoods = new GoodsInSpecGoods();
                $inSpecGoods->valuesSet([
                    'specTagId' => $tagIdStr,
                    'tagIdStr'  => $idStr,
                    'specGoodsPrice' => $data['specGoodsPrice'][$key],
                    'specGoodsStock' => $data['specGoodsStock'][$key],
                    'specGoodsItem'  => $data['specGoodsItem'][$key],
                    'specGoodsWeight'=> $data['specGoodsWeight'][$key],
                    'specGoodsUserGroupPrice' => serialize($data['specGoodsUserGroupPrice'][$tagIdStr]),
                    'goodsId' => $goodsId
                ]);
                $this->entityManager->persist($inSpecGoods);
                $this->entityManager->flush();

                $specGoodsItemStr .= $data['specGoodsItem'][$key] . ',';

                $inSpecGoodsIdArray[] = $inSpecGoods->getInSpecGoodsId();

                $this->entityManager->clear(GoodsInSpecGoods::class);
            }

            //删除不存在的规格商品会员组价格
            if (!empty($inSpecGoodsIdArray)) {
                $qb = $this->entityManager->createQueryBuilder();
                $qb->delete(GoodsInSpecGoodsGroupPrice::class, 'gp')
                    ->where('gp.goodsId = :goodsId')->setParameter('goodsId', $goodsId)
                    ->andWhere($qb->expr()->notIn('gp.inSpecGoodsId', $inSpecGoodsIdArray))
                    ->getQuery()->execute();
            }
        } else {
            $qb = $this->entityManager->createQueryBuilder();
            $qb->delete(GoodsInSpecGoods::class, 'i')->where('i.goodsId = :goodsId')->setParameter('goodsId', $goodsId)->getQuery()->execute();
            $qb->delete(GoodsInSpecGoodsGroupPrice::class, 'gp')->where('gp.goodsId = :goodsId')->setParameter('goodsId', $goodsId)->getQuery()->execute();
        }

        return empty($specGoodsItemStr) ? '' : ',' . $specGoodsItemStr;
    }

    /**
     * 单个更新规格商品信息
     * @param array $data
     * @param GoodsInSpecGoods $goodsInSpecGoods
     * @return GoodsInSpecGoods
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function updateOneInSpecGoods(array $data, GoodsInSpecGoods $goodsInSpecGoods)
    {
        $goodsInSpecGoods->valuesSet($data);
        $this->entityManager->flush();

        return $goodsInSpecGoods;
    }

    /**
     * 修改规格价格
     * @param array $data
     * @param $goodsId
     * @return void
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function editInSpecGoodsPrice(array $data, $goodsId)
    {
        if(isset($data['specTagIdStr']) && !empty($data['specTagIdStr'])) {
            $inSpecGoodsIdArray = [];
            $inSpecGoods        = $this->entityManager->getRepository(GoodsInSpecGoods::class)->findBy(['goodsId' => $goodsId]);
            if($inSpecGoods) foreach ($inSpecGoods as $sgValue) {
                $key = array_search($sgValue->getSpecTagId(), $data['specTagIdStr']);
                $sgValue->valuesSet([
                    'specGoodsPrice' => $data['specGoodsPrice'][$key],
                    'specGoodsUserGroupPrice' => serialize($data['specGoodsUserGroupPrice'][$sgValue->getSpecTagId()])
                ]);

                $inSpecGoodsIdArray[] = $sgValue->getInSpecGoodsId();

                unset($data['specTagIdStr'][$key]);

                $this->entityManager->flush();
            }

            //删除不存在的规格商品会员组价格
            if (!empty($inSpecGoodsIdArray)) {
                $qb = $this->entityManager->createQueryBuilder();
                $qb->delete(GoodsInSpecGoodsGroupPrice::class, 'gp')
                    ->where('gp.goodsId = :goodsId')->setParameter('goodsId', $goodsId)
                    ->andWhere($qb->expr()->notIn('gp.inSpecGoodsId', $inSpecGoodsIdArray))
                    ->getQuery()->execute();
            }
        }
    }

    /**
     * 根据商品id删除规格商品
     * @param $goodsId
     */
    public function deleteInSpecGoodsId($goodsId)
    {
        $qb = $this->entityManager->createQueryBuilder();
        $qb->delete(GoodsInSpecGoods::class, 's')->where('s.goodsId = :goodsId')->setParameter('goodsId', $goodsId);
        $qb->getQuery()->execute();
    }

    /**
     * 修改商品库存
     * @param $stockNum
     * @param $changeType
     * @param $inSpecGoodsId
     * @param $goodsId
     */
    public function editInSpecGoodsStock($stockNum, $changeType, $inSpecGoodsId, $goodsId)
    {
        $qb = $this->entityManager->createQueryBuilder();
        $qb->update(GoodsInSpecGoods::class, 's')->set('s.specGoodsStock', 's.specGoodsStock'.$changeType.$stockNum)
            ->where('s.inSpecGoodsId = :inSpecGoodsId')->setParameter('inSpecGoodsId', $inSpecGoodsId)
            ->andWhere('s.goodsId = :goodsId')->setParameter('goodsId', $goodsId);
        $qb->getQuery()->execute();
    }
}